/** **********************************************************************************
 * @file    9.C.c
 * @mainpage
 * @date    2013-10-05 13:39
 * @author  Alexey Kulikov <alexeyqu@gmail.com>, group 376, DCAM MIPT
 * @version 1.00
 *
 * Long binary totalizator.
 *
 * @par     The task.
 *          The program calculates sum of 2 long string-determined binary numbers
 *
 * @warning Length of each string < 1000
**************************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

#define DEBUG
#define MAX_LENGTH 1000

#ifdef DEBUG
    #define DBG printf ("# "),
    #define ASSERT(cond)                                                              \
    if (!(cond))                                                                      \
    {                                                                                 \
        printf ("Critical failure in assertion '%s'! \nfile %s, line %d \n"           \
                "Now keep calm and EXTERMINATE! EXTERMINATE! EXTERMINATE!!!\n"        \
                , #cond, __FILE__, __LINE__);                                         \
        abort();                                                                      \
    }
#else
    #define DBG if (0)
    #define ASSERT(cond)
#endif

/** ********************************************************************************
 * Input_Numbers - reads 2 long binary numbers and saves them in 2 strings
 *
 * @param   num_1[]     first number
 *          num_2[]     second number
 *          length_1    length of the first string
 *          length_2    length of the second string
************************************************************************************/
void Input_Numbers (int num_1[], int num_2[],
                    int* length_1, int* length_2);

/** ********************************************************************************
 * Summarize - calculates sum of 2 binary numbers and puts it into another
 *
 * @param   num_1[]     first number
 *          num_2[]     second number
 *          sum[]       sum
 *          length_1    length of the first string
 *          length_2    length of the second string
************************************************************************************/
int Summarize (int num_1[], int num_2[], int sum[],
               int length_1, int length_2);

int main()
{
    DBG printf ("C language test'07. \n");
    DBG printf ("9.C problem. \n");
    DBG printf ("Long binary totalizator. \n");
    DBG printf ("Enter 2 binary numbers, each in one string: \n->\n");

    int num_1[MAX_LENGTH] = {0}, num_2[MAX_LENGTH] = {0}; //!< 2 numbers to summarize
    int sum[MAX_LENGTH] = {0}; //!< Sum
    int length_1 = 0, length_2 = 0; //!< lengths of strings
    int len_sum = 0; //!< Length of sum
    int i = 0; //!< Counter

    Input_Numbers (num_1, num_2, &length_1, &length_2);

    DBG printf ("Length of numbers: %d and %d\n", length_1, length_2);

    len_sum = Summarize (num_1, num_2, sum, length_1, length_2);

    DBG printf ("Result: \n->");

    if (sum[0] == 1) printf ("1");
    for (i = 1; i < len_sum; i++)
    {
        printf ("%d", sum[i]);
    }

    return 0;
}

void Input_Numbers (int num_1[], int num_2[],
                    int* length_1, int* length_2)
{
    char c = 0; //!< Temporary input symbol

    /// Read first number
    while ((c = getchar()) != '\n')
    {
        ASSERT (c == '0' || c == '1');
        num_1[(*length_1)++] = c - '0';
        ASSERT (*length_1 < MAX_LENGTH);
    }

    /// Read second number
    while ((c = getchar()) != '\n')
    {
        ASSERT (c == '0' || c == '1');
        num_2[(*length_2)++] = c - '0';
        ASSERT (*length_2 < MAX_LENGTH);
    }
}

int Summarize (int num_1[], int num_2[], int sum[],
               int length_1, int length_2)
{
    int i = 0; //!< Counter
    int len_sum = 0; //!< Length of sum

    len_sum = (length_1 > length_2)? length_1 : length_2;
    len_sum++; //!< Considering transfer on next order while calculating
    ASSERT (len_sum < MAX_LENGTH);

    for (i = 1; i < len_sum; i++)
    {
        if (length_1 - i >= 0 && length_2 - i >= 0)
        {
            sum[len_sum - i] += num_1[length_1 - i] + num_2[length_2 - i];
        }

        if (length_1 - i < 0)
        {
            sum[len_sum - i] += num_2[length_2 - i];
        }

        if (length_2 - i < 0)
        {
            sum[len_sum - i] += num_1[length_1 - i];
        }

        while (sum[len_sum - i] > 1) {sum[len_sum - i]-= 2; sum[len_sum - i - 1]++;}
    }

    return len_sum;
}
